import { _decorator, Camera, Component, EventTouch, find, Input, input, instantiate, Node, physics, Prefab, Vec2, Vec3 } from 'cc';
import { Sword } from './Sword';
import { Player } from './Player';
const { ccclass, property } = _decorator;

@ccclass('GameManager')
export class GameManager extends Component {
    private finalDir: Vec2 = new Vec2();
    private launchForce: Vec2 = new Vec2(100, 150); // 设置默认发射力度
    private swordGravity: number = 9.8; // 设置默认重力
    private numberOfDots: number = 40; // 设置默认点数量
    private spaceBetweenDots: number = 0.4; // 增加点间距
    private freezeTimeDuration: number = 0.5; // 设置默认冻结时间
    private touchPos: Vec2 = new Vec2();
    private touchStartPos: Vec2 = new Vec2();
    private isDragging: boolean = false;
    @property(Prefab)
    dotPrefab: Prefab = null!;
    @property(Node)
    dotsParent: Node = null!;
    @property(Node)
    player: Node = null!;
    @property(Prefab)
    swordPrefab: Prefab = null!;
    @property
    dots: any[] = [];

    private playerComp: Player;

    protected onLoad(): void {
        this.playerComp = this.player.getComponent(Player);
    }

    protected onEnable(): void {
        input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }
    protected onDisable(): void {
        input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
        input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
        input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
    }

    start() {
        this.generateDots();
    }

    update(deltaTime: number) {

    }

    public createSword() {
        const newSword = instantiate(this.swordPrefab);
        newSword.position = this.player.position;
        newSword.parent = this.node;
        const newSwordComp = newSword.getComponent(Sword);
        newSwordComp.setUpSword(this.finalDir, this.swordGravity, this.playerComp, this.freezeTimeDuration);
    }

    public aimDirection(): Vec2 {
        const playerPos = this.player.position;
        const direction = new Vec2(
            this.touchPos.x - playerPos.x,
            this.touchPos.y - playerPos.y
        );
        return direction;
    }

    private onTouchStart(event: EventTouch) {
        this.isDragging = true;
        event.getLocation(this.touchStartPos);
        this.dotsActive(true);
    }

    private onTouchMove(event: EventTouch) {
        if (this.isDragging) {
            event.getLocation(this.touchPos);
            for (let i = 0; i < this.dots.length; i++) {
                const time = i * this.spaceBetweenDots;
                const pos = new Vec2(
                    this.player.position.x + this.aimDirection().normalize().x * this.launchForce.x * time,
                    this.player.position.y + this.aimDirection().normalize().y * this.launchForce.y * time - 0.5 * this.swordGravity * (time * time)
                );
                this.dots[i].position = new Vec3(pos.x, pos.y, 0);
            }
            const delta = this.touchStartPos.subtract(this.touchPos);
            const rawAngle = Math.atan2(-delta.y, -delta.x);
            this.playerComp.rotateBone(rawAngle);
        }
    }

    private onTouchEnd(event: EventTouch) {
        if (this.isDragging) {
            this.finalDir = new Vec2(
                this.aimDirection().normalize().x * this.launchForce.x * 0.56,
                this.aimDirection().normalize().y * this.launchForce.y * 0.56,
            );
            this.dotsActive(false);
            this.createSword();
            this.playerComp.playAnim('animation', false);
            this.isDragging = false;
        }
        this.scheduleOnce(() => {
            this.playerComp.resetBoneRotation();
        }, 0.2)
    }

    public dotsActive(_isActive: boolean) {
        for (let i = 0; i < this.dots.length; i++) {
            this.dots[i].active = _isActive;
        }
    }

    private generateDots() {
        this.dots = new Array<Node>(this.numberOfDots);
        for (let i = 0; i < this.numberOfDots; i++) {
            this.dots[i] = instantiate(this.dotPrefab);
            this.dots[i].position = this.player.position;
            this.dots[i].parent = this.dotsParent;
            this.dots[i].active = false;
        }
    }

}


